package handler

import (
	"common-service/models"
	pbBanner "common-service/proto/banner"
	pbParams "common-service/proto/params"
	pbResult "common-service/proto/result"
	"common-service/tools"
	"context"
	"math"
	"strings"
	"time"

	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

/*
 +----------------------------------------------------------------------
 + Title        : BannerHandler
 + Author       : huwl
 + Version      : 1.0.0
 + Initial-Time : 2019-08-08
 + Last-time    : 这个文件最后修改的时间 + 修改人的名称
 + Desc         : 横幅处理
 +----------------------------------------------------------------------
*/

type BannerHandler struct {
	pbBanner.UnimplementedBannerSrvServer
}

/**
 * 新增
 *
 * @param string Title -------------------------------------------必传,标题
 * @param string ImageUrl ----------------------------------------非必传,图片
 * @param uint32 Type --------------------------------------------非必传,类型
 * @param string Link --------------------------------------------非必传,链接
 * @param string Note --------------------------------------------非必传,备注
 * @param uint32 Sort --------------------------------------------非必传,排序
 * @return *pbResult.Result, error
 * @author huwl
 */
func (e *BannerHandler) AddBanner(ctx context.Context, req *pbBanner.AddBannerRequest) (*pbResult.Result, error) {
	if req.Title == "" {
		return nil, status.Errorf(codes.InvalidArgument, "标题不能为空")
	}

	result, err := models.Banner{}.Add(&models.Banner{
		Title:    req.Title,
		ImageUrl: req.ImageUrl,
		Type:     uint8(req.Type),
		Link:     req.Link,
		Note:     req.Note,
		Sort:     uint16(req.Sort),
		Status:   1,
	})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	if result <= 0 {
		return nil, status.Errorf(codes.Aborted, "新增横幅失败")
	}

	return &pbResult.Result{
		Code: 200,
		Msg:  "新增横幅成功",
	}, nil
}

/**
 * 删除
 *
 * @param string Ids ---------------------------------------------必传,横幅Id,支持多个
 * @return *pbResult.Result, error
 * @author huwl
 */
func (e *BannerHandler) DeleteBanner(ctx context.Context, req *pbParams.IdsRequest) (*pbResult.Result, error) {
	ids := strings.TrimRight(req.Ids, ",")

	if ids == "" {
		return nil, status.Errorf(codes.InvalidArgument, "横幅ID错误")
	}

	result, err := models.Banner{}.EditByParams(&models.Banner{}, map[string]interface{}{"status": -2, "update_time": time.Now()}, map[string]interface{}{"id in (?)": tools.IntSplit(ids, ",")})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	if result <= 0 {
		return nil, status.Errorf(codes.Aborted, "删除横幅失败")
	}

	return &pbResult.Result{
		Code: 200,
		Msg:  "删除横幅成功",
	}, nil
}

/**
 * 编辑
 *
 * @param uint64 Id ----------------------------------------------必传,横幅Id
 * @param string Title -------------------------------------------非必传,标题
 * @param string ImageUrl ----------------------------------------非必传,图片
 * @param uint32 Type --------------------------------------------非必传,类型
 * @param string Link --------------------------------------------非必传,链接
 * @param string Note --------------------------------------------非必传,备注
 * @param uint32 Sort --------------------------------------------非必传,排序
 * @return *pbResult.Result, error
 * @author huwl
 */
func (e *BannerHandler) EditBanner(ctx context.Context, req *pbBanner.EditBannerRequest) (*pbResult.Result, error) {
	if req.Id <= 0 {
		return nil, status.Errorf(codes.InvalidArgument, "横幅Id错误")
	}

	params := map[string]interface{}{
		"update_time": time.Now(),
	}
	if req.Title != "" {
		params["title"] = req.Title
	}
	if req.ImageUrl != "" {
		params["image_url"] = req.ImageUrl
	}
	if req.Type > 0 {
		params["type"] = req.Type
	}
	if req.Link != "" {
		params["link"] = req.Link
	}
	if req.Sort > 0 {
		params["sort"] = req.Sort
	}
	if req.Note != "" {
		params["note"] = req.Note
	}

	result, err := models.Banner{}.EditByPrimaryKey(&models.Banner{}, params, req.Id)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	if result <= 0 {
		return nil, status.Errorf(codes.Aborted, "编辑横幅失败")
	}

	return &pbResult.Result{
		Code: 200,
		Msg:  "编辑横幅成功",
	}, nil
}

/**
 * 编辑状态
 *
 * @param string Ids ---------------------------------------------必传,横幅Id支持多个
 * @param int32 Status -------------------------------------------必传,状态
 * @return *pbResult.Result, error
 * @author huwl
 */
func (e *BannerHandler) EditBannerStatus(ctx context.Context, req *pbParams.EditStatusRequest) (*pbResult.Result, error) {
	ids := strings.TrimRight(req.Ids, ",")

	if ids == "" {
		return nil, status.Errorf(codes.InvalidArgument, "横幅Id错误")
	}
	if !tools.IsContainNumber([]int{-1, 1}, int(req.Status)) {
		return nil, status.Errorf(codes.InvalidArgument, "横幅状态错误")
	}

	result, err := models.Banner{}.EditByParams(&models.Banner{}, map[string]interface{}{
		"status":      req.Status,
		"update_time": time.Now(),
	}, map[string]interface{}{"id IN (?)": tools.IntSplit(ids, ",")})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	message := ""

	if req.Status == 1 {
		message = "启用横幅"
	} else {
		message = "禁用横幅"
	}
	if result <= 0 {
		return nil, status.Errorf(codes.Aborted, message+"失败")
	}

	return &pbResult.Result{
		Code: 200,
		Msg:  message + "成功",
	}, nil
}

/**
 * 详情
 *
 * @param uint64 id ----------------------------------------------必传,横幅Id
 * @return *pbBanner.BannerResponse, error
 * @author huwl
 */
func (e *BannerHandler) BannerDetail(ctx context.Context, req *pbParams.DetailRequest) (*pbBanner.BannerResponse, error) {
	if req.Id <= 0 {
		return nil, status.Errorf(codes.InvalidArgument, "横幅ID错误")
	}

	//获取横幅信息
	banner := models.Banner{}
	result, err := models.Banner{}.GetResultByPrimaryKey(&banner, req.Id)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	if result <= 0 || banner.Status == -2 {
		return nil, status.Errorf(codes.Aborted, "横幅信息错误")
	}

	return &pbBanner.BannerResponse{
		Banner: &pbBanner.Banner{
			Id:         uint64(banner.Id),
			Title:      banner.Title,
			ImageUrl:   banner.ImageUrl,
			Type:       uint32(banner.Type),
			Link:       banner.Link,
			Sort:       uint32(banner.Sort),
			Status:     int32(banner.Status),
			CreateTime: banner.CreateTime.Format("2006-01-02 15:04:05"),
			UpdateTime: banner.UpdateTime.Format("2006-01-02 15:04:05"),
		},
	}, nil
}

/**
 * 列表
 *
 * @param uint64 Id ----------------------------------------------非必传,主键
 * @param string Ids ---------------------------------------------非必传,多个主键
 * @param string Title -------------------------------------------非必传,标题
 * @param string Type --------------------------------------------非必传,类型
 * @param string Status ------------------------------------------非必传,状态
 * @param string StartCreateTime ---------------------------------非必传,开始创建时间
 * @param string EndCreateTime -----------------------------------非必传,结束创建时间
 * @param string sortField ---------------------------------------非必传,排序字段
 * @param string sortType ----------------------------------------非必传,排序方式
 * @param uint32 PageSize ----------------------------------------非必传,条数
 * @param uint32 Page --------------------------------------------非必传,页码
 * @return *pbBanner.BannerListResponse, error
 * @author huwl
 */
func (e *BannerHandler) BannerList(ctx context.Context, req *pbBanner.QueryBannerRequest) (*pbBanner.BannerListResponse, error) {
	params := map[string]interface{}{
		"status <> ?": -2,
	}

	page := req.Page
	pageSize := req.PageSize
	sortType := req.SortType
	sortField := req.SortField

	if req.Id > 0 {
		params["id"] = req.Id
	}
	if req.Ids != "" {
		params["id IN (?)"] = tools.IntSplit(strings.TrimRight(req.Ids, ","), ",")
	}
	if req.Title != "" {
		params["title"] = req.Title
	}
	if req.Type != "all" {
		params["type"] = req.Type
	}
	if req.Status != "all" {
		params["status in (?)"] = tools.IntSplit(req.Status, ",")
	}
	if req.StartCreateTime != "" {
		params["create_time >= ?"] = req.StartCreateTime + " 00:00:00"
	}
	if req.EndCreateTime != "" {
		params["create_time <= ?"] = req.EndCreateTime + " 23:59:59"
	}
	if page <= 0 {
		page = 1
	}
	if pageSize == 0 {
		pageSize = 20
	}
	if sortField == "" {
		sortField = "id"
	}
	if sortType == "" {
		sortType = "desc"
	}

	var total int64
	err := models.Banner{}.GetTotalByParams(&models.Banner{}, &total, params)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	banners := []*pbBanner.Banner{}
	bannerItems := []models.Banner{}
	if total > 0 {
		err := models.Banner{}.GetResultsByParams(&models.Banner{}, &bannerItems, params, int(page), int(pageSize), sortField+" "+sortType)
		if err != nil {
			return nil, status.Errorf(codes.Aborted, err.Error())
		}

		for _, bannerItem := range bannerItems {
			banners = append(banners, &pbBanner.Banner{
				Id:         uint64(bannerItem.Id),
				Title:      bannerItem.Title,
				ImageUrl:   bannerItem.ImageUrl,
				Type:       uint32(bannerItem.Type),
				Link:       bannerItem.Link,
				Note:       bannerItem.Note,
				Sort:       uint32(bannerItem.Sort),
				Status:     int32(bannerItem.Status),
				CreateTime: bannerItem.CreateTime.Format("2006-01-02 15:04:05"),
				UpdateTime: bannerItem.UpdateTime.Format("2006-01-02 15:04:05"),
			})
		}
	}

	pageTotal := math.Ceil(float64(total) / float64(pageSize))
	return &pbBanner.BannerListResponse{
		ListResult: &pbResult.ListCommonResult{
			Page:      page,
			Total:     uint32(total),
			PageSize:  pageSize,
			PageTotal: uint32(pageTotal),
		},
		Banners: banners,
	}, nil
}

/**
 * 数量
 *
 * @param uint64 Id ----------------------------------------------非必传,主键
 * @param string Ids ---------------------------------------------非必传,多个主键
 * @param string Title -------------------------------------------非必传,标题
 * @param string Type --------------------------------------------非必传,类型
 * @param string Status ------------------------------------------非必传,状态
 * @param string StartCreateTime ---------------------------------非必传,开始创建时间
 * @param string EndCreateTime -----------------------------------非必传,结束创建时间
 * @return *pbResult.TotalResult, error
 * @author huwl
 */
func (e *BannerHandler) BannerTotal(ctx context.Context, req *pbBanner.QueryBannerRequest) (*pbResult.TotalResult, error) {
	params := map[string]interface{}{
		"status <> ?": -2,
	}

	page := req.Page
	pageSize := req.PageSize
	sortType := req.SortType
	sortField := req.SortField

	if req.Id > 0 {
		params["id"] = req.Id
	}
	if req.Ids != "" {
		params["id IN (?)"] = tools.IntSplit(strings.TrimRight(req.Ids, ","), ",")
	}
	if req.Title != "" {
		params["title"] = req.Title
	}
	if req.Type != "all" {
		params["type"] = req.Type
	}
	if req.Status != "all" {
		params["status in (?)"] = tools.IntSplit(req.Status, ",")
	}
	if req.StartCreateTime != "" {
		params["create_time >= ?"] = req.StartCreateTime + " 00:00:00"
	}
	if req.EndCreateTime != "" {
		params["create_time <= ?"] = req.EndCreateTime + " 23:59:59"
	}
	if page <= 0 {
		page = 1
	}
	if pageSize == 0 {
		pageSize = 20
	}
	if sortType == "" {
		sortType = "id"
	}
	if sortField == "" {
		sortType = "desc"
	}

	var total int64
	err := models.Banner{}.GetTotalByParams(&models.Banner{}, &total, params)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	return &pbResult.TotalResult{
		Total: uint32(total),
	}, nil
}

/**
 * 单条信息
 *
 * @param string Title -------------------------------------------非必传,标题
 * @param string Status ------------------------------------------非必传,状态
 * @param string Type --------------------------------------------非必传,类型
 * @return *pbBanner.BannerResponse, error
 * @author huwl
 */
func (e *BannerHandler) Row(ctx context.Context, req *pbBanner.QueryBannerRequest) (*pbBanner.BannerResponse, error) {
	params := map[string]interface{}{}

	if req.Title != "" {
		params["title"] = req.Title
	}
	if req.Status != "all" {
		params["status in (?)"] = tools.IntSplit(req.Status, ",")
	}
	if req.Type != "all" {
		params["position"] = req.Type
	}

	banner := models.Banner{}
	i, err := models.Banner{}.Row(&models.Banner{}, &banner, params)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	if i <= 0 || banner.Status == -2 {
		return nil, status.Errorf(codes.Aborted, "横幅信息错误")
	}

	return &pbBanner.BannerResponse{
		Banner: &pbBanner.Banner{
			Id:         uint64(banner.Id),
			Title:      banner.Title,
			ImageUrl:   banner.ImageUrl,
			Type:       uint32(banner.Type),
			Link:       banner.Link,
			Sort:       uint32(banner.Sort),
			Status:     int32(banner.Status),
			CreateTime: banner.CreateTime.Format("2006-01-02 15:04:05"),
			UpdateTime: banner.UpdateTime.Format("2006-01-02 15:04:05"),
		},
	}, nil
}

/**
 * 多横幅ID获取信息
 *
 * @param string ids ---------------------------------------------必传,横幅Id多个
 * @return *pbBanner.BannerListResponse, error
 * @author huwl
 */
func (e *BannerHandler) Rows(ctx context.Context, req *pbParams.IdsRequest) (*pbBanner.BannerListResponse, error) {
	ids := strings.TrimRight(req.Ids, ",")

	if ids == "" {
		return nil, status.Errorf(codes.InvalidArgument, "横幅ID错误")
	}

	banners := []models.Banner{}
	bannerIds := tools.IntSplit(ids, ",")
	bannerItemIds := []interface{}{}
	for _, bannerId := range bannerIds {
		bannerItemIds = append(bannerItemIds, bannerId)
	}
	err := models.Banner{}.Rows(&banners, bannerItemIds)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	bannerItems := []*pbBanner.Banner{}
	for _, banner := range banners {
		bannerItems = append(bannerItems, &pbBanner.Banner{
			Id:         uint64(banner.Id),
			Title:      banner.Title,
			ImageUrl:   banner.ImageUrl,
			Type:       uint32(banner.Type),
			Link:       banner.Link,
			Sort:       uint32(banner.Sort),
			Status:     int32(banner.Status),
			CreateTime: banner.CreateTime.Format("2006-01-02 15:04:05"),
			UpdateTime: banner.UpdateTime.Format("2006-01-02 15:04:05"),
		})
	}

	return &pbBanner.BannerListResponse{
		Banners: bannerItems,
	}, nil
}
